// secondary.js
import frameFormat from "@/utils/unpackFrame/frame.json";
import {telemetryParser} from "@/utils/byteParser.js";

/**
 * 滑动窗口搜索
 * @param buffer
 * @returns {*[]}
 */
export function unpackFrame(buffer) {
    const dv = new DataView(buffer);
    const frames = [];
    const FRAME_SIZE = 256;
    const FRAME_START = 0xEB90;
    const FRAME_END = 0x09D7;

    let offset = 0;
    while (offset + FRAME_SIZE <= dv.byteLength) {
        const startMarker = dv.getUint16(offset, false);
        const endMarker = dv.getUint16(offset + FRAME_SIZE - 2, false);

        if (startMarker === FRAME_START && endMarker === FRAME_END) {
            frames.push(buffer.slice(offset, offset + FRAME_SIZE));
            offset += FRAME_SIZE;
        } else {
            offset++;
        }
    }
    return frames;
}

function getFrameConfig(hexString) {
    return frameFormat[0].params[3].enum[hexString]
}

/**
 * 解析工程遥测扫捕跟帧,并根据内层帧类型的枚举解析出具体帧数据
 * @param buffer
 * @returns {Array<Object>}
 */
export function unpackEB9A(buffer) {
    const dv = new DataView(buffer);
    // 获取第四个字节内容
    const frameType = dv.getUint8(4); // 直接读取类型字节
    // todo: 判断工程遥测类型
    const frameKey = `0x${frameType.toString(16).padStart(2, '0')}`; // 确保格式一致
    const config = getFrameConfig(frameKey);
    const partialBuffer = buffer.slice(8, -3)
    const fmtLst = frameFormat[0].params[3].enum["0x" + frameType.toString(16)].params.map(item => `${item.type}${item.bit_length}`)
    return telemetryParser(
        config.params,
        partialBuffer,
        true,
        fmtLst
    );
}

// ----------新版---------------------------------
// 只在模块加载时初始化 frame 配置和格式缓存
const frameConfigCache = {
    "0x55": getFrameConfig("0x55"),
    "0x88": getFrameConfig("0x88"),
};

const fmtCache = Object.freeze({
    "0x55": Object.freeze(
        frameFormat[0].params[3].enum["0x55"].params.map(({type, bit_length}) => `${type}${bit_length}`)
    ),
    "0x88": Object.freeze(
        frameFormat[0].params[3].enum["0x88"].params.map(({type, bit_length}) => `${type}${bit_length}`)
    ),
});

function unpackFrames(buffers, type) {
    const config = frameConfigCache[type];
    const fmtLst = fmtCache[type];

    return buffers.map(bf => telemetryParser(config.params, bf.slice(8, -3), fmtLst));
}

export function unpackEB9AFrames(buffers) {
    return unpackFrames(buffers, "0x55");
}

export function unpackEB94Frames(buffers) {
    return unpackFrames(buffers, "0x88");
}

export function unpackFrameParser(buffers) {
    const frames = unpackFrame(buffers);
    if (!frames.length) return [];

    const frameType = new DataView(frames[0]).getUint8(4);
    return frameType === 0x55 ? unpackEB9AFrames(frames) :
        frameType === 0x88 ? unpackEB94Frames(frames) :
            [];
}

/**
 * 处理图像数据并生成灰度图（base64格式）。
 * @param {ArrayBuffer[]} dataList - 存储图像数据的 ArrayBuffer 数组
 * @param {number} xPixel - 图像宽度（像素数）
 * @param {number} yPixel - 图像高度（像素数）
 * @param {number} maxGray - 最大灰度值，默认 16383
 * @param {number} badPointThreshold - 坏点阈值，当数据超过 maxGray 时设为该值，默认 16383
 * @returns {string|null} 返回 PNG 格式的 base64 数据URL，如果出错则返回 null
 */
export function processAndGenerateImage(dataList, xPixel, yPixel, maxGray = 16383, badPointThreshold = 16383) {
    // 1. 合并所有 ArrayBuffer 为一个连续的 Uint8Array
    const totalLength = dataList.reduce((sum, buffer) => sum + buffer.byteLength, 0);
    const combined = new Uint8Array(totalLength);
    let offset = 0;
    dataList.forEach(buffer => {
        combined.set(new Uint8Array(buffer), offset);
        offset += buffer.byteLength;
    });

    // 2. 利用 DataView 按大端序读取 16 位无符号整数
    const totalPixels = xPixel * yPixel;
    if (combined.byteLength < totalPixels * 2) {
        console.error("数据长度不足以构成指定尺寸的图像。");
        return null;
    }
    const uint16Data = new Uint16Array(totalPixels);
    const dataView = new DataView(combined.buffer, combined.byteOffset, combined.byteLength);
    for (let i = 0; i < totalPixels; i++) {
        // 第二个参数 false 指定大端序读取
        uint16Data[i] = dataView.getUint16(i * 2, false);
    }

    // 3. 处理图像数据
    const pixelValues = new Uint8ClampedArray(totalPixels * 4);
    let overexposedPixels = 0;
    for (let i = 0; i < totalPixels; i++) {
        // 取低 14 位
        let value = uint16Data[i] & 0x3FFF;
        if (value > maxGray) {
            value = badPointThreshold;
        }
        if (value === maxGray) {
            overexposedPixels++;
        }
        // 归一化到 0~255
        const normalized = Math.round((value / maxGray) * 255);
        pixelValues[i * 4] = normalized;       // R
        pixelValues[i * 4 + 1] = normalized;     // G
        pixelValues[i * 4 + 2] = normalized;     // B
        pixelValues[i * 4 + 3] = 255;            // A
    }
    console.log(`过曝像素个数：${overexposedPixels}`);

    // 4. 使用 Canvas 绘制图像并生成 base64 格式 PNG 数据
    const canvas = document.createElement('canvas');
    canvas.width = xPixel;
    canvas.height = yPixel;
    const ctx = canvas.getContext('2d');
    const imageData = new ImageData(pixelValues, xPixel, yPixel);
    ctx.putImageData(imageData, 0, 0);

    const base64Image = canvas.toDataURL('image/png');
    console.log("生成的图像 base64 数据：", base64Image);
    return base64Image;
}